Here are two patches which update the hypercall interfaces to
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 5 Jul 2005 16:08:03 +0000 (16:08 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 5 Jul 2005 16:08:03 +0000 (16:08 +0000)
use 64-bit values for both page table entries and physical
addresses.  These changes are needed to use more than 4GB with
PAE paging enabled.

The first patch is a pretty straightforward update for xen, it
simply makes the values 64-bit wide everythere.

The second patch adapts the linux kernel to the hypercall
interface changes.  It also introduces two MULTI_* functions
(for the update_va_mapping hypercalls) which have simliar
behavior like the HYPERVISOR_* counterparts but fill
multicall_entry_t instead of doing the call directly.

The tools don't need source code changes, but must be rebuilt
due to the change in the xen public header file.

Domain0 boots fine, unpriviliged domain boots fine with fully
functional networking.  Note this is non-PAE mode, tools don't
have support for PAE domU boots yet.

Signed-off-by: Gerd Knorr <kraxel@suse.de>
linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c
linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6.11-xen-sparse/drivers/xen/usbback/usbback.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/hypercall.h
linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
xen/arch/x86/mm.c
xen/include/public/dom0_ops.h
xen/include/public/xen.h

index 8f78b2376c5046a2912078c00eb0d08da1f7946f..f44c70eb0344d7c82bd4cd115b49a723ed020ac1 100644 (file)
@@ -141,10 +141,8 @@ static void fast_flush_area(int idx, int nr_pages)
 
     for ( i = 0; i < nr_pages; i++ )
     {
-        mcl[i].op = __HYPERVISOR_update_va_mapping;
-        mcl[i].args[0] = MMAP_VADDR(idx, i);
-        mcl[i].args[1] = 0;
-        mcl[i].args[2] = 0;
+       MULTI_update_va_mapping(mcl+i, MMAP_VADDR(idx, i),
+                               __pte(0), 0);
     }
 
     mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
@@ -545,11 +543,10 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
 
     for ( i = 0; i < nseg; i++ )
     {
-        mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
-        mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
-        mcl[i].args[1] = (seg[i].buf & PAGE_MASK) | remap_prot;
-        mcl[i].args[2] = 0;
-        mcl[i].args[3] = blkif->domid;
+       MULTI_update_va_mapping_otherdomain(
+           mcl+i, MMAP_VADDR(pending_idx, i),
+           pfn_pte_ma(seg[i].buf >> PAGE_SHIFT, remap_prot),
+           0, blkif->domid);
 #ifdef CONFIG_XEN_BLKDEV_TAP_BE
         if ( blkif->is_blktap )
             mcl[i].args[3] = ID_TO_DOM(req->id);
index faf6458083fabab332d646c49620e4d004286cfe..45e542919d8322d3ca8b3cfc19c065495610bd97 100644 (file)
@@ -234,11 +234,9 @@ static void net_rx_action(unsigned long unused)
          * Heed the comment in pgtable-2level.h:pte_page(). :-)
          */
         phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
-        
-        mcl->op = __HYPERVISOR_update_va_mapping;
-        mcl->args[0] = vdata;
-        mcl->args[1] = (new_mfn << PAGE_SHIFT) | __PAGE_KERNEL;
-        mcl->args[2] = 0;
+
+        MULTI_update_va_mapping(mcl, vdata,
+                               pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
         mcl++;
 
         mcl->op = __HYPERVISOR_mmuext_op;
@@ -425,10 +423,8 @@ static void net_tx_action(unsigned long unused)
     while ( dc != dp )
     {
         pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-        mcl[0].op = __HYPERVISOR_update_va_mapping;
-        mcl[0].args[0] = MMAP_VADDR(pending_idx);
-        mcl[0].args[1] = 0;
-        mcl[0].args[2] = 0;
+       MULTI_update_va_mapping(mcl, MMAP_VADDR(pending_idx),
+                               __pte(0), 0);
         mcl++;     
     }
 
@@ -571,11 +567,10 @@ static void net_tx_action(unsigned long unused)
         /* Packets passed to netif_rx() must have some headroom. */
         skb_reserve(skb, 16);
 
-        mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain;
-        mcl[0].args[0] = MMAP_VADDR(pending_idx);
-        mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL;
-        mcl[0].args[2] = 0;
-        mcl[0].args[3] = netif->domid;
+       MULTI_update_va_mapping_otherdomain(
+           mcl, MMAP_VADDR(pending_idx),
+           pfn_pte_ma(txreq.addr >> PAGE_SHIFT, PAGE_KERNEL),
+           0, netif->domid);
         mcl++;
 
         memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
index 0ae6f7a40a445a985f080c86dc755878b5db251f..419a2c336bfad4acf806bff72837d6461d3205ad 100644 (file)
@@ -395,10 +395,8 @@ static void network_alloc_rx_buffers(struct net_device *dev)
        phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] 
            = INVALID_P2M_ENTRY;
 
-        rx_mcl[i].op = __HYPERVISOR_update_va_mapping;
-        rx_mcl[i].args[0] = (unsigned long)skb->head;
-        rx_mcl[i].args[1] = 0;
-        rx_mcl[i].args[2] = 0;
+       MULTI_update_va_mapping(rx_mcl+i, (unsigned long)skb->head,
+                               __pte(0), 0);
     }
 
     /* After all PTEs have been zapped we blow away stale TLB entries. */
@@ -585,10 +583,8 @@ static int netif_poll(struct net_device *dev, int *pbudget)
         mmu->ptr  = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
         mmu->val  = __pa(skb->head) >> PAGE_SHIFT;
         mmu++;
-        mcl->op = __HYPERVISOR_update_va_mapping;
-        mcl->args[0] = (unsigned long)skb->head;
-        mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL;
-        mcl->args[2] = 0;
+       MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
+                               pfn_pte_ma(rx->addr >> PAGE_SHIFT, PAGE_KERNEL), 0);
         mcl++;
 
         phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 
index ac73bd0f2fde8c23aad797045e731973af0262bb..ad803ab3f505fc8a072c88a1c617db259031cb11 100644 (file)
@@ -189,10 +189,8 @@ static void fast_flush_area(int idx, int nr_pages)
 
     for ( i = 0; i < nr_pages; i++ )
     {
-        mcl[i].op = __HYPERVISOR_update_va_mapping;
-        mcl[i].args[0] = MMAP_VADDR(idx, i);
-        mcl[i].args[1] = 0;
-        mcl[i].args[2] = 0;
+       MULTI_update_va_mapping(mcl+i, MMAP_VADDR(idx, i),
+                               __pte(0), 0);
     }
 
     mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
@@ -651,11 +649,10 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
     for ( i = 0, offset = 0; offset < req->length;
           i++, offset += PAGE_SIZE )
     {
-       mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
-       mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
-        mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot;
-        mcl[i].args[2] = 0;
-        mcl[i].args[3] = up->domid;
+       MULTI_update_va_mapping_otherdomain(
+           mcl+i, MMAP_VADDR(pending_idx, i),
+           pfn_pte_ma(buffer_mach >> PAGE_SHIFT, remap_prot),
+           0, up->domid);
         
         phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
             FOREIGN_FRAME((buffer_mach + offset) >> PAGE_SHIFT);
@@ -667,11 +664,10 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
     if ( req->pipe_type == 0 && req->num_iso > 0 ) /* Maybe schedule ISO... */
     {
         /* Map in ISO schedule, if necessary. */
-        mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
-        mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
-        mcl[i].args[1] = (req->iso_schedule & PAGE_MASK) | remap_prot;
-        mcl[i].args[2] = 0;
-        mcl[i].args[3] = up->domid;
+       MULTI_update_va_mapping_otherdomain(
+           mcl+i, MMAP_VADDR(pending_idx, i),
+           pfn_pte_ma(req->iso_schedule >> PAGE_SHIFT, remap_prot),
+           0, up->domid);
 
         phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
             FOREIGN_FRAME(req->iso_schedule >> PAGE_SHIFT);
index 98b2b999fd3a7f3f4bfaabe25540efb691cc9ff8..3abe82e3df0a33cd5c470c89208918f5c6e7076e 100644 (file)
@@ -371,13 +371,19 @@ HYPERVISOR_update_va_mapping(
     unsigned long va, pte_t new_val, unsigned long flags)
 {
     int ret;
-    unsigned long ign1, ign2, ign3;
+    unsigned long ign1, ign2, ign3, ign4;
 
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
        : "0" (__HYPERVISOR_update_va_mapping), 
-          "1" (va), "2" ((new_val).pte_low), "3" (flags)
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
+#else
+         "3" (0),
+#endif
+         "4" (flags)
        : "memory" );
 
     if ( unlikely(ret < 0) )
@@ -473,13 +479,20 @@ HYPERVISOR_update_va_mapping_otherdomain(
     unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
 {
     int ret;
-    unsigned long ign1, ign2, ign3, ign4;
+    unsigned long ign1, ign2, ign3, ign4, ign5;
 
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
+         "=S" (ign4), "=D" (ign5)
        : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
-          "1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
+#else
+         "3" (0),
+#endif
+         "4" (flags), "5" (domid) :
         "memory" );
     
     return ret;
index a2929951d2a0a3a4b7e1889e66ba90e9a9396ebe..0ee9e3d12ec8f14662106b5531ea989811f0b2bb 100644 (file)
@@ -139,4 +139,49 @@ unsigned long allocate_empty_lowmem_region(unsigned long pages);
 
 #include <asm/hypercall.h>
 
+static inline void
+MULTI_update_va_mapping(
+    multicall_entry_t *mcl, unsigned long va,
+    pte_t new_val, unsigned long flags)
+{
+    mcl->op = __HYPERVISOR_update_va_mapping;
+    mcl->args[0] = va;
+#if defined(CONFIG_X86_64)
+    mcl->args[1] = new_val.pte;
+    mcl->args[2] = flags;
+#elif defined(CONFIG_X86_PAE)
+    mcl->args[1] = new_val.pte_low;
+    mcl->args[2] = new_val.pte_high;
+    mcl->args[3] = flags;
+#else
+    mcl->args[1] = new_val.pte_low;
+    mcl->args[2] = 0;
+    mcl->args[3] = flags;
+#endif
+}
+
+static inline void
+MULTI_update_va_mapping_otherdomain(
+    multicall_entry_t *mcl, unsigned long va,
+    pte_t new_val, unsigned long flags, domid_t domid)
+{
+    mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
+    mcl->args[0] = va;
+#if defined(CONFIG_X86_64)
+    mcl->args[1] = new_val.pte;
+    mcl->args[2] = flags;
+    mcl->args[3] = domid;
+#elif defined(CONFIG_X86_PAE)
+    mcl->args[1] = new_val.pte_low;
+    mcl->args[2] = new_val.pte_high;
+    mcl->args[3] = flags;
+    mcl->args[4] = domid;
+#else
+    mcl->args[1] = new_val.pte_low;
+    mcl->args[2] = 0;
+    mcl->args[3] = flags;
+    mcl->args[4] = domid;
+#endif
+}
+
 #endif /* __HYPERVISOR_H__ */
index 06e47e5eea97563980ca10acbe31abc8b775921b..2c530cf26114b97c24845d6fef82c081356b9323 100644 (file)
@@ -2020,7 +2020,8 @@ int do_mmu_update(
             }
 
             va = map_domain_page_with_cache(mfn, &mapcache);
-            va = (void *)((unsigned long)va + (req.ptr & ~PAGE_MASK));
+            va = (void *)((unsigned long)va +
+                          (unsigned long)(req.ptr & ~PAGE_MASK));
             page = &frame_table[mfn];
 
             switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
@@ -2164,7 +2165,7 @@ int do_mmu_update(
             break;
 
         default:
-            MEM_LOG("Invalid page update command %lx", req.ptr);
+            MEM_LOG("Invalid page update command %x", cmd);
             break;
         }
 
@@ -2251,11 +2252,10 @@ int update_grant_va_mapping(unsigned long va,
 }
 
 
-int do_update_va_mapping(unsigned long va,
-                         unsigned long val32,
+int do_update_va_mapping(unsigned long va, u64 val64,
                          unsigned long flags)
 {
-    l1_pgentry_t   val = l1e_from_intpte(val32);
+    l1_pgentry_t   val = l1e_from_intpte(val64);
     struct vcpu   *v   = current;
     struct domain *d   = v->domain;
     unsigned int   cpu = v->processor;
@@ -2349,8 +2349,7 @@ int do_update_va_mapping(unsigned long va,
     return rc;
 }
 
-int do_update_va_mapping_otherdomain(unsigned long va,
-                                     unsigned long val32,
+int do_update_va_mapping_otherdomain(unsigned long va, u64 val64,
                                      unsigned long flags,
                                      domid_t domid)
 {
@@ -2368,7 +2367,7 @@ int do_update_va_mapping_otherdomain(unsigned long va,
         return -ESRCH;
     }
 
-    rc = do_update_va_mapping(va, val32, flags);
+    rc = do_update_va_mapping(va, val64, flags);
 
     return rc;
 }
index 19ad0efab584b28cb9ef9c6c2f2364911f86fffb..419e6477462a216b03bffe019d4b7926cf3c8da5 100644 (file)
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA100A
+#define DOM0_INTERFACE_VERSION   0xAAAA100B
 
 /************************************************************************/
 
index 357761f544b5c1c5b0375d9eceb184845d306131..3e25532f1979573bc319d6417712820a6f54f839 100644 (file)
@@ -274,8 +274,8 @@ typedef u16 domid_t;
  */
 typedef struct
 {
-    memory_t ptr;       /* Machine address of PTE. */
-    memory_t val;       /* New contents of PTE.    */
+    u64 ptr;       /* Machine address of PTE. */
+    u64 val;       /* New contents of PTE.    */
 } mmu_update_t;
 
 /*